package chapter4_对象组合.线程安全性委托;

import annotation.Immutable;
import annotation.ThreadSafe;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * 委托方式实现线程安全
 *
 * 分析：DelegatingVehicleTracker的线程安全委托给ConcurrentMap<String, Point> locations去保障，注意这里Point为不可变对象
 */
@ThreadSafe
public class DelegatingVehicleTracker {
    private final ConcurrentMap<String, Point> locations;
    private final Map<String, Point> unmodifiableMap;

    public DelegatingVehicleTracker(Map<String, Point> points) {
        this.locations = new ConcurrentHashMap<>(points); // ConcurrentHashMap底层为每一个元素创建一个Node节点
        this.unmodifiableMap = Collections.unmodifiableMap(locations);
    }

    public Map<String, Point> getLocations() {
        return unmodifiableMap;
    }

    public Point getLocation(String id) {
        return locations.get(id);
    }

    public void setLocation(String id, int x, int y) {
        //因Point是不可变对象，此处需要进行替换操作
        if (locations.replace(id, new Point(x, y)) == null) {
            throw new IllegalArgumentException("invalid vehicle name:" + id);
        }
    }

    public static void main(String[] args) {
        Map<String, Point> map = new HashMap<>();
        map.put("one", new Point(1,1));
        map.put("two", new Point(2,2));
        ConcurrentHashMap<String, Point> concurrentHashMap = new ConcurrentHashMap<>(map);
        Point one = concurrentHashMap.get("one");
        concurrentHashMap.replace("one", new Point(7,7));
    }
}

@Immutable
class Point {
    public final int x, y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}
